package api_servers {
	
//	import com.adobe.serialization.json.JSON;
	
	import UIUtils.uif_json;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.utils.Timer;
	/*
	import vk.MD5;
	import vk.MyJson;
	*/
	
	public dynamic class api_server extends EventDispatcher{
	    public var app_id:String = '';
	    public var secret:String = null;
	    protected var _wait_count: int;
	    protected var _queryIndent: Array;
	    protected var _timerLimit: int;
	    
	    public var api_url:String = null;
	    public var viewer_id: String = '';
		public var user_id: String = '';
		protected var sroot: Object;
		protected var _cache: Object;
		
		public function api_server(a_sroot: Object, api_url: String, viewer_id: String, app_id: String, secret: String, timerLimit:int=100) {
			super();
			this.api_url = api_url;
			this.app_id = app_id;
			this.secret = secret;
			this.viewer_id = viewer_id;
			this._queryIndent = new Array();
			this._timerLimit = timerLimit;
			this.sroot = a_sroot;
			_cache = new Object();

			if (this._timerLimit) {
				_wait_count = 0;
				var w_timer:Timer = new Timer(this._timerLimit);
				w_timer.addEventListener( TimerEvent.TIMER, function(e: TimerEvent): void {
					if (_wait_count > 0) _wait_count--;
				});
				w_timer.start();
			}
		}
		
		public function get flashVars(): Object {
			return null;
		}
		
		public function isAdmin(): Boolean {
			return false;
		}
		
		protected function getSig( arr: Array): String {
			var sig2: String = '';
			for( var i:uint = 0; i < arr.length; i++ ) {
				sig2 += arr[i].pn + '=' + arr[i].pv;
			}
			return viewer_id + sig2 + secret;
		}
		
		public function makeSig( arr:Array ):String {
			import MD5;
			return MD5.encrypt( getSig(arr) );
//			return sig;
		}
		
	    private function delQuotes( s_:String ):String
	    {
	      var s:String = s_;
	      if ( s ) {
	        s = s.replace( /<br>/g, "\n" );
	        s = s.replace( /&amp;/g, "\&" );
	        s = s.replace( /&quot;/g, "\"" );
	        s = s.replace( /&\#34;/g, "\"" );
	        s = s.replace( /&\#39;/g, "\'" );
	        s = s.replace( /\\\\"/g, "\"" );
	      }
	      return s;
	    }
	    
		protected function srHelper( arr:Array):URLVariables {// sendRequestHelper
			return null;
		}
		
		private function indexQuery(queryID:String): int {
			if (queryID) {
				for (var i:int=0;i<_queryIndent.length;i++)
					if (_queryIndent[i].queryID == queryID) return i;
			}
			return -1;
		}
		
// Работа с актуальными запросами
		private function removeQuery(queryID:String): void {
			var l_queryIndex:int = indexQuery(queryID);
			if (l_queryIndex > -1) _queryIndent.splice(l_queryIndex, 1); 
		}
		
		private function isQuery(queryID:String): Boolean {
			return (queryID && (indexQuery(queryID) > -1));
		}
		
		private function addQuery(a_queryID:String): int {
			var l_queryUnique:int = Math.round(Math.random() * 1000);
			_queryIndent.push({queryID:a_queryID, queryUnique:l_queryUnique});
    		return l_queryUnique;
		}
		
		private function actualQuery(a_queryID:String, a_queryUnique: int): Boolean {
			if (!a_queryUnique) return true;
			
			var index: int = indexQuery(a_queryID);
			return ((index > -1) && (_queryIndent[index].queryUnique == a_queryUnique)); 
		}
		
//--------------------
		public function createRequest(a_vars: Array, a_url: String='', method: String = ''): URLRequest {
	    	var url_vars: URLVariables = srHelper(a_vars);
			var urlRequest:URLRequest = new URLRequest(a_url?a_url:api_url);
			urlRequest.method = (method?method:URLRequestMethod.POST);
			if (urlRequest.method == URLRequestMethod.POST) urlRequest.data = url_vars; 
			else urlRequest.url += '?' + url_vars.toString();
			
			return urlRequest;
		}
		
	    public function jsrHelper( a_vars: Array, handler_:* =null, a_queryID:String='', 
	    							a_cache: Boolean = false, a_url: String = '', request: URLRequest=null,
	    							onError: Function=null):void {

			if (a_cache && _cache.hasOwnProperty(a_queryID)) {
				if (handler_) handler_(_cache[a_queryID]);
				return;
			}	    	
	    	var l_queryUnique:int = 0;
	    	if (a_queryID) {
		    	removeQuery(a_queryID);
				l_queryUnique = addQuery(a_queryID);
	    	}
	    		
	    	function sendRequest(a_queryUnique: int): void {
	    		
	    		if (actualQuery(a_queryID, a_queryUnique)) { // Проверка актуальности запроса
					var urlRequest:URLRequest = (request!=null)?request:createRequest(a_vars, a_url);
					
				    function doErrHandler( e: IOErrorEvent ):void {
				    	if (onError != null) onError(e);
				   		sroot.dispatchEvent(new GDataEvent(GDataEvent.RESPONSE, {
			   				queryID: a_queryID,
			   				error_code: -2,
			   				error_msg: e.text
				   		}));
				    }
				    
				    function doSecurityErrHandler( e: SecurityErrorEvent ):void {
				    	if (onError != null) onError(e);
				   		sroot.dispatchEvent(new GDataEvent(GDataEvent.RESPONSE, {
			   				queryID: a_queryID,
			   				error_code: -1,
			   				error_msg: e.text
				   		}));
				    }
				    
					function _request(e: Event): void {
						var resultLoader: URLLoader = URLLoader(e.target);
						var data:* = getResponseData(resultLoader.data);
			    		if (data) {
			    			sroot.dispatchEvent(new GDataEvent(GDataEvent.RESPONSE, {queryID: a_queryID, response: data}));
				    		if (actualQuery(a_queryID, a_queryUnique)) { // Проверка актуальности запроса
								removeQuery(a_queryID); // Удаляем запрос из списка актуальных
								if (handler_) {
									var res_data:* = prepareData(a_queryID, data);
									if (res_data) {
										if (a_cache && a_queryID)
											_cache[a_queryID] = res_data;
										handler_(res_data);
									}
								}
				    		}
			    		}
					} 
					  
					var ldr:URLLoader = new URLLoader();
					sroot.dispatchEvent(new GDataEvent(GDataEvent.REQUEST, {queryID:a_queryID}));
				    
					ldr.addEventListener( Event.COMPLETE, _request );
					ldr.addEventListener( IOErrorEvent.IO_ERROR,  doErrHandler);
					ldr.addEventListener( SecurityErrorEvent.SECURITY_ERROR, doSecurityErrHandler);
					ldr.load( urlRequest );
				}
	    	}
	    	
			if (this._timerLimit) {
		    	// Размерено отправляем запросы не меньше чем через 1 сек.
		    	if (_wait_count > 0) {
			    	var l_cur_wait:int = _wait_count;
		    		var timer: Timer = new Timer(this._timerLimit);
		    		timer.addEventListener(TimerEvent.TIMER, function(e: TimerEvent): void {
		    			l_cur_wait--;
		    			if (l_cur_wait == 0) {
			    			timer.stop();
		    				sendRequest(l_queryUnique);
		    			}
		    		});
	    			timer.start();
		    	} else sendRequest(l_queryUnique);
		    	
	    		_wait_count += 10;
	  		} else sendRequest(l_queryUnique);
	    }
	    
	    protected function prepareData(a_queryID:String, data:*):* {
	    	return data;
	    }
	    
	    public function getResponseData(strData: String): * {
	    	strData = strData.replace(/Ñ\?/g, 'ш');
	    	strData = strData.replace(/Ð\?/g, 'И');
	    	strData = strData.replace(/&quot;/g, '');
	    	var data: * = null;
	    	try {
	    		data = uif_json.d(delQuotes(strData));
	    	} catch (err: Error) {
	    		data = null;
	    		sroot.dispatchEvent(new GDataEvent(GDataEvent.ERRORDATARESPONSE, strData));
	    	}
	    	return data;
	    }
	    
	    public function getProfiles(uids: String, handler_:*, fields: String='', queryID:String=''): void {
	    }
	    
	    public function getInstall(uids: String, handler_:*, queryID:String='', a_app_id: String=''): void {
	    }
	    
	    public function getFriends(uid: String, handler_:*, queryID:String=''): void {
	    	
	    }
	    
	    public function streamPublish(text: String, post: String, handler_:*=null, queryID:String='', img: int=66): void {
	    	
	    }
	}
}